package main

import (
	"sync"
	"time"
)

type SafeMap struct {

	// 声明一个线程不安全的 map，这个 map 会受到 sync.Mutex 的保护
	safeMap map[int]int

	// 不声明变量，SafeMap 的变量 s 可以直接调用 Lock() 和 unlock()
	sync.Mutex
}

func (s *SafeMap)Read(k int) (int, bool) {
	s.Lock()
	defer s.Unlock()
	result, ok := s.safeMap[k]
	return result, ok
}

// 为结构体添加一个方法
func (s *SafeMap)Write(k,v int) {

	s.Lock()
	defer s.Unlock()

	// 对 map 的写操作会加载加锁和释放锁之间
	s.safeMap[k] = v
}

func main() {
	//unsafeWrite()
	safeWrite()
	time.Sleep(time.Second)
}

func safeWrite() {

	// 声明一个结构体，该结构体会包裹一个线程不安全的 map
	s := SafeMap {
		safeMap: map[int]int{},
		Mutex: sync.Mutex{},
	}

	for i := 0; i < 100; i++ {
		go func() {
			// Write 方法在操作 map 时会加锁和释放锁
			s.Write(1,1)
		}()
	}
}

func unsafeWrite() {
	conflictMap := map[int]int{}
	for i := 0; i < 100; i++ {
		go func() {
			conflictMap[1] = i // => fatal error: concurrent map writes
		}()
	}
}
